#include <cstdlib>
#include "Functions.h"

Function::~Function(){}

double Var::value(double x) const {
    return x;
}

Const::Const() : number_(0) {}
Const::Const(std::string function) : number_( atof( function.c_str() ) ) {}
double Const::value(double x) const {
    return number_;
}

Plus::Plus() {}
Plus::Plus(Function * left, Function * right) : CompositeFunction(left, right) {}
Plus::Plus(Plus const & copy): CompositeFunction(copy) {}
double Plus::value(double x) const {
    return left_->value(x) + right_->value(x);
}

Minus::Minus() {}
Minus::Minus(Function * left, Function * right) : CompositeFunction(left, right) {}
Minus::Minus(Minus const & copy): CompositeFunction(copy) {}
double Minus::value(double x) const {
    return left_->value(x) - right_->value(x);
}

Mult::Mult() {}
Mult::Mult(Function * left, Function * right) : CompositeFunction(left, right) {}
Mult::Mult(Mult const & copy): CompositeFunction(copy) {}
double Mult::value(double x) const {
    return left_->value(x) * right_->value(x);
}

Devide::Devide() {}
Devide::Devide(Function * left, Function * right) : CompositeFunction(left, right) {}
Devide::Devide(Devide const & copy): CompositeFunction(copy) {}
double Devide::value(double x) const {
    return left_->value(x) / right_->value(x);
}


CompositeFunction::CompositeFunction() : left_ (new Const("0")), right_ (new Const("0")), copy_counter_(0) {}
CompositeFunction::CompositeFunction(Function * left, Function * right) :
                        left_(left), right_(right), copy_counter_(new int(1)) {}
CompositeFunction::CompositeFunction(CompositeFunction const & copy) :
                        left_(copy.left_), right_(copy.right_), copy_counter_(copy.copy_counter_) {
    if(copy_counter_ != 0)
        ++(*copy_counter_);
}
CompositeFunction & CompositeFunction::operator=(CompositeFunction const & right) {
    if(this != &right && right.copy_counter_ != 0) {
        left_ = right.left_;
        right_ = right.right_;
        copy_counter_ = right.copy_counter_;
        ++(*copy_counter_);
    }
    return *this;
}
CompositeFunction::~CompositeFunction() {
    if(copy_counter_ != 0) {
        if(*copy_counter_ == 1) {
           delete left_;
           delete right_;
           delete copy_counter_;
        } else {
           --(*copy_counter_);
        }
    }
}